BUSINESS QUESTIONS: Note: ignore the fact there is no question 1,
this is due to a formatting error 2. a) Is there are a trend in injuries
By Region, and is there different peaks of times of year per region? b)
Analysis on the types of animals that are injured, this also by Region –
is there a species that is more liable to injury in certain regions? -
(cat/dog by region) c) What is the outcome? Does this differ by
region?
- Total call volume for complaint calls: How has this trended over
time?
- Is there a particular animal being called about the most?
- Do particular suburbs have different type of complaint calls? Do
they call about different animals? ((MAKE A LEAFLET MAP FOR THIS!))
- Business Intelligence – using the insights you have found, can you
predict how this might look for the upcoming year?
library(tidyverse)
library(tsibble)
Attaching package: ‘tsibble’
The following object is masked from ‘package:lubridate’:
interval
The following objects are masked from ‘package:base’:
intersect, setdiff, union
library(forecast)
Registered S3 method overwritten by 'quantmod':
method from
as.zoo.data.frame zoo
This is forecast 8.20
Stackoverflow is a great place to get help on R issues:
http://stackoverflow.com/tags/forecasting+r.
source("cleaning_script.R")
Rows: 31330 Columns: 7── Column specification ─────────────────────────────────────────────────────────
Delimiter: ","
chr (6): nature, animal_type, category, suburb, date_range, city
lgl (1): responsible_office
ℹ Use `spec()` to retrieve the full column specification for this data.
ℹ Specify the column types or set `show_col_types = FALSE` to quiet this message.Warning: Expected 2 pieces. Missing pieces filled with `NA` in 5643 rows [7, 11, 12, 18, 19, 25, 27, 29, 30, 31, 39, 44, 52, 54, 66, 67, 74, 75, 78, 81, ...].Rows: 42413 Columns: 5── Column specification ─────────────────────────────────────────────────────────
Delimiter: ","
chr (5): Animal Type, Complaint Type, Date Received, Suburb, Electoral Division
ℹ Use `spec()` to retrieve the full column specification for this data.
ℹ Specify the column types or set `show_col_types = FALSE` to quiet this message.Rows: 664 Columns: 12── Column specification ─────────────────────────────────────────────────────────
Delimiter: ","
chr (2): animal_type, outcome
dbl (10): year, ACT, NSW, NT, QLD, SA, TAS, VIC, WA, Total
ℹ Use `spec()` to retrieve the full column specification for this data.
ℹ Specify the column types or set `show_col_types = FALSE` to quiet this message.
Note; summer in Australia seasons: Summer: December - February
Autumn: March - May Winter: June - August Spring: September -
November
also: The ‘wet season’ in Australia’s North: November - April
https://www.mdpi.com/2076-2615/8/7/100 will useful
reading for later, talk about the need to reduce euthanasia or similar
and the effect this has on people
Intro: Introduce the point of the talk, talk about Australian RSPCA,
talk about how the data was gathered (using the information from the
websites), the PURPOSE of this investigation (which is to help the RSPCA
know which areas/animals to focus their efforts on), as I’m introducing
the datasets I can introduce the two different cities. First, we can
talk a short bit about Australia as a whole, it’s climate, the kind of
animals etc. The point here is to really set the scene before diving too
deep into facts and figures, as especially a non-technical audience this
will help keep them engaged and make a more holistic presentation. In my
opinion, it’s always good to zoom out and see the big picture, rather
than getting lost in the myopia of some csv files.
Townsville Intro: Townsville is a city on the north-eastern coast of
Queensland, Australia. With a population of 180,820 as of June 2018, it
is the largest settlement in North Queensland; it is unofficially
considered its capital. [note: put a map of Australia with Queensland
and Townsville highlighted here. Talk a little bit about the population
density, urbanisation, climate, types of animals that are common here
etc. Show some photos of the area too]
Brisbane Intro: Exact same as above
3.
- Total call volume for complaint calls: How has this trended over
time?
First, let’s look at the Townsville animal complaints.
animal_complaints %>%
group_by(date_received) %>%
summarise(count = n()) %>%
ggplot(aes(x = date_received, y = count)) +
geom_line() +
scale_x_date(date_breaks = "6 months", date_labels = "%b-%y")

This shows some seasonality and also an increase then a decline. Each
summer (in December) the calls are much lower, rising again each Winter.
Using geom_smooth, we get:
animal_complaints %>%
group_by(date_received) %>%
summarise(count = n()) %>%
ggplot(aes(x = date_received, y = count)) +
geom_smooth() +
geom_point() +
scale_x_date(date_breaks = "1 year", date_labels = "%y")

This shows a bit more clearly the general trend of call volume. From
2014 it steadily rises, peaking in 2017. Afterwards, it steadily
declines to only slightly higher than where it started. It would be very
difficult to say whether this trend will continue downward, go upward or
stay relatively flat.
Note; if we have time or if it’s helpful, we will fix this graph so
that quarters are properly displayed.
brisbane_complaints %>%
group_by(date) %>%
summarise(count = n()) %>%
ggplot(aes(x = date, y = count)) +
geom_point() +
geom_line() +
scale_x_date(date_breaks = "3 months", date_labels = "%y")

Again, we see the seasonality of winter having more calls. The fact
this is in both Brisbane and Townsville suggests a fairly general
trend.
brisbane_complaints %>%
group_by(date) %>%
summarise(count = n()) %>%
ggplot(aes(x = date, y = count)) +
geom_point() +
geom_smooth() +
scale_x_date(date_breaks = "1 year", date_labels = "20%y")

Other than declining a little over 2016, the number of calls sees a
slow but steady increase towards 2020, being thousands more than it was
in 2016 and 2017. So, the general trend is that the RSPCA are getting
more complaints as time goes on. Now, this does not necessarily mean the
line will continue to go up. We are also missing Q3 from 2016 so this
skews the curve a little
3.
- Is there a particular animal being called about the most?
animal_complaints %>%
group_by(animal_type) %>%
ggplot(aes(x = animal_type)) +
geom_bar()

The number of calls about dogs dwarf those about cats hugely. Let’s
look at specific numbers:
animal_complaints %>%
group_by(animal_type) %>%
count() %>%
summarise(n, 4094 / 38319)
So cats account for only 10% of the calls dogs do for Townsville!
Let’s look at Brisbane:
brisbane_complaints %>%
group_by(type_of_animal) %>%
count()
brisbane_complaints %>%
group_by(type_of_animal) %>%
ggplot(aes(x = type_of_animal)) +
geom_bar()

We have a lot more animal types here that we don’t in the previous
data. We also have many calls about Attacks with no animal specified,
many of which it is very likely they were involving dogs. However, we
can’t say this for sure.
So that makes
4745 / 13334 # cats are 35% of the calls compared to dogs
[1] 0.3558572
# all other animals divided by dogs, leaving out unspecified (which we believe potentially contain a high proportion of dogs)
9457 / 13349
[1] 0.7084426
Most of the other animals have very small counts, interestingly foxes
seem to make up a decent proportion of the calls regarding wild
animals.
To answer the question however, it’s mainly dogs and cats, and
especially dogs. Dogs are being called about more than any of the other
animals combined (if we leave Unspecified to the side)
(Attack refers to the initial description of the complaint)
3.
- Do particular suburbs have different type of complaint calls? Do
they call about different animals?
OK, so this one is difficult simply for the fact there is a huge
amount of suburbs.
brisbane_complaints %>%
group_by(suburb) %>%
count()
# There is 192 suburbs! Certainly using a fill on a graph is not gonna work, neither is putting them on the x-axis on a bar graph.
animal_complaints %>%
group_by(suburb) %>%
count()
# 85 suburbs for Townsville
animal_complaints %>%
group_by(electoral_division) %>%
count()
# also 11 electoral divisions. Could we look at suburbs one electoral division at a time? Possibly
Idea: What about using leaflet to visualise types of complaint calls
on a map?
This is more feasible with the Townsville datasets, as it has less
suburbs and only 6 types of complaints. It may be necessary to try and
wrangle the Brisbane data a little further to narrow down categories
(for both type_of_animal and complaint_type)
FOR TOWNSVILLE WE HAVE: 85 different suburbs 6 complaint types 2
animal types
We want to break it down by suburb and complaint type, and then by
suburb and animal type
animal_complaints %>%
ggplot(aes(x = suburb, fill = animal_type)) +
geom_bar(position = "fill") +
coord_flip() +
scale_x_discrete(guide = guide_axis(n.dodge = 5))

animal_complaints %>%
ggplot(aes(x = suburb, fill =complaint_type)) +
geom_bar(position = "fill")

#coord_flip() +
#scale_x_discrete(guide = guide_axis(n.dodge = 5))
The challenge again, is having too many suburbs that we can’t get any
useful information out of the graphs
animal_complaints %>%
group_by(suburb) %>%
count(sort = TRUE)
# let's drop any suburbs with less than 200 cases
animal_complaints %>%
group_by(suburb) %>%
summarise(count = n(), animal_type) %>%
filter(count >= 500) %>%
ggplot(aes(x = suburb, y = count, fill = animal_type)) +
geom_col() +
coord_flip()
`summarise()` has grouped output by 'suburb'. You can override using the `.groups` argument.

The highest count by quite a large margin is unallocated to a
specific suburb.
animal_complaints %>%
group_by(suburb) %>%
summarise(count = n(), animal_type) %>%
filter(count >= 500) %>%
ggplot(aes(x = suburb, y = count, fill = animal_type)) +
geom_col(position = "fill") +
coord_flip()
`summarise()` has grouped output by 'suburb'. You can override using the `.groups` argument.

At a glance, there’s no big difference on animal types. All the
suburbs have a large majority of dogs. Could we do a hypothesis test to
see if there is a statistically significant difference?
animal_complaints %>%
group_by(suburb) %>%
summarise(count = n(), animal_type) %>%
filter(count < 500 & count > 100) %>%
ggplot(aes(x = suburb, y = count, fill = animal_type)) +
geom_col(position = "fill") +
coord_flip()
`summarise()` has grouped output by 'suburb'. You can override using the `.groups` argument.

Looking at the lower end of the population, we see an outlier.
Townsville City has way more cats than any of the other suburbs. In
fact, it’s almost 50/50!
Now still looking at the Townsville dataset, we’ll break it down by
complaint type:
animal_complaints %>%
group_by(suburb) %>%
summarise(count = n(), complaint_type) %>%
filter(count >= 500 & count <= 4000) %>%
ggplot(aes(x = suburb, y = count, fill = complaint_type)) +
geom_col(position = "fill") +
coord_flip()
`summarise()` has grouped output by 'suburb'. You can override using the `.groups` argument.

Now for the lower end of the count:
animal_complaints %>%
group_by(suburb) %>%
summarise(count = n(), complaint_type) %>%
filter(count < 500 & count > 50) %>%
ggplot(aes(x = suburb, y = count, fill = complaint_type)) +
geom_col(position = "fill") +
coord_flip()
`summarise()` has grouped output by 'suburb'. You can override using the `.groups` argument.

I’m not sure much can be gleamed with so many complaint_types. Let’s
try focusing more specifically.
One thing to note here, is the vast variation in tolerance for noise.
Most categories are consistent except this one. Cluden for example has a
small percentage of noise complaints,while Bohle Plains has a huge
percentage. This requires more investigation to figure out the root
cause of this:
animal_complaints %>%
group_by(suburb) %>%
summarise(count = n(), complaint_type) %>%
filter(count >= 500) %>%
filter(complaint_type == "Noise" | (complaint_type == "Attack")) %>%
ggplot(aes(x = suburb, y = count, fill = complaint_type)) +
geom_col(position = "fill") +
coord_flip()
`summarise()` has grouped output by 'suburb'. You can override using the `.groups` argument.

animal_complaints %>%
group_by(suburb) %>%
summarise(count = n(), complaint_type) %>%
filter(count >= 500) %>%
filter(complaint_type == "Noise" | (complaint_type == "Aggressive Animal")) %>%
ggplot(aes(x = suburb, y = count, fill = complaint_type)) +
geom_col(position = "fill") +
coord_flip()
`summarise()` has grouped output by 'suburb'. You can override using the `.groups` argument.

animal_complaints %>%
group_by(suburb) %>%
summarise(count = n(), complaint_type) %>%
filter(count >= 500) %>%
filter(complaint_type == "Wandering" | (complaint_type == "Aggressive Animal")) %>%
ggplot(aes(x = suburb, y = count, fill = complaint_type)) +
geom_col(position = "fill") +
coord_flip()
`summarise()` has grouped output by 'suburb'. You can override using the `.groups` argument.

animal_complaints %>%
group_by(suburb) %>%
summarise(count = n(), complaint_type) %>%
filter(count >= 500) %>%
filter(complaint_type == "Enclosure" | (complaint_type == "Noise")) %>%
ggplot(aes(x = suburb, y = count, fill = complaint_type)) +
geom_col(position = "fill") +
coord_flip()
`summarise()` has grouped output by 'suburb'. You can override using the `.groups` argument.

For the less than 500 greater than 50 groups:
animal_complaints %>%
group_by(suburb) %>%
summarise(count = n(), complaint_type) %>%
filter(count < 500 & count > 100) %>%
filter(complaint_type == "Noise" | (complaint_type == "Attack")) %>%
ggplot(aes(x = suburb, y = count, fill = complaint_type)) +
geom_col(position = "fill") +
coord_flip()
`summarise()` has grouped output by 'suburb'. You can override using the `.groups` argument.

animal_complaints %>%
group_by(suburb) %>%
summarise(count = n(), complaint_type) %>%
filter(count < 500 & count > 100) %>%
filter(complaint_type == "Noise" | (complaint_type == "Aggressive Animal")) %>%
ggplot(aes(x = suburb, y = count, fill = complaint_type)) +
geom_col(position = "fill") +
coord_flip()
`summarise()` has grouped output by 'suburb'. You can override using the `.groups` argument.

animal_complaints %>%
group_by(suburb) %>%
summarise(count = n(), complaint_type) %>%
filter(count < 500 & count > 100) %>%
filter(complaint_type == "Wandering" | (complaint_type == "Aggressive Animal")) %>%
ggplot(aes(x = suburb, y = count, fill = complaint_type)) +
geom_col(position = "fill") +
coord_flip()
`summarise()` has grouped output by 'suburb'. You can override using the `.groups` argument.

animal_complaints %>%
group_by(suburb) %>%
summarise(count = n(), complaint_type) %>%
filter(count < 500 & count > 100) %>%
#filter(complaint_type == "Enclosure" | (complaint_type == "Noise")) %>%
ggplot(aes(x = suburb, y = count, fill = complaint_type)) +
geom_col(position = "fill") +
coord_flip() +
facet_wrap(~ suburb)
`summarise()` has grouped output by 'suburb'. You can override using the `.groups` argument.

animal_complaints %>%
group_by(suburb) %>%
summarise(count = n(), complaint_type, animal_type) %>%
filter(count < 500 & count > 100) %>%
ggplot(aes(x = complaint_type, y = count, fill = complaint_type)) +
geom_col() +
facet_wrap(~ suburb)
`summarise()` has grouped output by 'suburb'. You can override using the `.groups` argument.

From this graph, we can see that Hyde Park has a disproportionate
amount of private impounds, while Bohle plains has more noise
complaints.
Potential hypothesis test:
That the level of private impounds in Hyde Park being greater is
statistically significant.
That the level of noise in Bohle Plains being greater is
statistically significant.
animal_complaints %>%
group_by(suburb) %>%
count() %>%
filter(n < 500 & n > 100)
Let’s look at the suburbs with much higher complaints now:
animal_complaints %>%
group_by(suburb) %>%
summarise(count = n(), complaint_type, animal_type) %>%
filter(count >= 500 & count <4000) %>%
ggplot(aes(x = complaint_type, y = count, fill = complaint_type)) +
geom_col() +
facet_wrap(~ suburb)
`summarise()` has grouped output by 'suburb'. You can override using the `.groups` argument.

2. a) Is there are a trend in injuries By Region, and is there
different peaks of times of year per region?
It’s impossible to say if there’s different peaks of times of yer per
region, as we only have the data for the year as a whole. Unless we look
at Suburb rather than region, and break this down by time. However, I
think it’d be good to use the general Autralia (nationwide) data.
animal_outcomes %>%
group_by(region) %>%
ggplot(aes(x = region, y = number_of_occurences, fill = outcome, col = outcome)) +
geom_col(position = "fill")

animal_outcomes %>%
group_by(region, year) %>%
summarise(count = n())
`summarise()` has grouped output by 'region'. You can override using the `.groups` argument.
LS0tCnRpdGxlOiAiQW5hbHlzaXMiCm91dHB1dDogaHRtbF9ub3RlYm9vawotLS0KCkJVU0lORVNTIFFVRVNUSU9OUzoKTm90ZTogaWdub3JlIHRoZSBmYWN0IHRoZXJlIGlzIG5vIHF1ZXN0aW9uIDEsIHRoaXMgaXMgZHVlIHRvIGEgZm9ybWF0dGluZyBlcnJvcgoyLiAKYSkgSXMgdGhlcmUgYXJlIGEgdHJlbmQgaW4gaW5qdXJpZXMgQnkgUmVnaW9uLCBhbmQgaXMgdGhlcmUgZGlmZmVyZW50IHBlYWtzIG9mIHRpbWVzIG9mIHllYXIgcGVyIHJlZ2lvbj8KYikgQW5hbHlzaXMgb24gdGhlIHR5cGVzIG9mIGFuaW1hbHMgdGhhdCBhcmUgaW5qdXJlZCwgdGhpcyBhbHNvIGJ5IFJlZ2lvbiDigJMgaXMgdGhlcmUgYSBzcGVjaWVzIHRoYXQgaXMgbW9yZSBsaWFibGUgdG8gaW5qdXJ5IGluIGNlcnRhaW4gcmVnaW9ucz8gLSAoY2F0L2RvZyBieSByZWdpb24pCmMpIFdoYXQgaXMgdGhlIG91dGNvbWU/IERvZXMgdGhpcyBkaWZmZXIgYnkgcmVnaW9uPwoKMy4KYSkgVG90YWwgY2FsbCB2b2x1bWUgZm9yIGNvbXBsYWludCBjYWxsczogSG93IGhhcyB0aGlzIHRyZW5kZWQgb3ZlciB0aW1lPwpiKSBJcyB0aGVyZSBhIHBhcnRpY3VsYXIgYW5pbWFsIGJlaW5nIGNhbGxlZCBhYm91dCB0aGUgbW9zdD8KYykgRG8gcGFydGljdWxhciBzdWJ1cmJzIGhhdmUgZGlmZmVyZW50IHR5cGUgb2YgY29tcGxhaW50IGNhbGxzPyBEbyB0aGV5IGNhbGwgYWJvdXQgZGlmZmVyZW50IGFuaW1hbHM/ICgoTUFLRSBBIExFQUZMRVQgTUFQIEZPUiBUSElTISkpCgo0LgpCdXNpbmVzcyBJbnRlbGxpZ2VuY2Ug4oCTIHVzaW5nIHRoZSBpbnNpZ2h0cyB5b3UgaGF2ZSBmb3VuZCwgY2FuIHlvdSBwcmVkaWN0IGhvdyB0aGlzIG1pZ2h0IGxvb2sgZm9yIHRoZSB1cGNvbWluZyB5ZWFyPwoKYGBge3J9CmxpYnJhcnkodGlkeXZlcnNlKQpsaWJyYXJ5KHRzaWJibGUpCmxpYnJhcnkoZm9yZWNhc3QpCnNvdXJjZSgiY2xlYW5pbmdfc2NyaXB0LlIiKQpgYGAKCk5vdGU7IHN1bW1lciBpbiBBdXN0cmFsaWEgc2Vhc29uczoKU3VtbWVyOiBEZWNlbWJlciAtIEZlYnJ1YXJ5CkF1dHVtbjogTWFyY2ggLSBNYXkKV2ludGVyOiBKdW5lIC0gQXVndXN0ClNwcmluZzogU2VwdGVtYmVyIC0gTm92ZW1iZXIKCmFsc286IFRoZSAnd2V0IHNlYXNvbicgaW4gQXVzdHJhbGlhJ3MgTm9ydGg6IE5vdmVtYmVyIC0gQXByaWwKCmh0dHBzOi8vd3d3Lm1kcGkuY29tLzIwNzYtMjYxNS84LzcvMTAwICAgd2lsbCB1c2VmdWwgcmVhZGluZyBmb3IgbGF0ZXIsIHRhbGsgYWJvdXQgdGhlIG5lZWQgdG8gcmVkdWNlIGV1dGhhbmFzaWEgb3Igc2ltaWxhciBhbmQgdGhlIGVmZmVjdCB0aGlzIGhhcyBvbiBwZW9wbGUKCkludHJvOgpJbnRyb2R1Y2UgdGhlIHBvaW50IG9mIHRoZSB0YWxrLCB0YWxrIGFib3V0IEF1c3RyYWxpYW4gUlNQQ0EsIHRhbGsgYWJvdXQgaG93IHRoZSBkYXRhIHdhcyBnYXRoZXJlZCAodXNpbmcgdGhlIGluZm9ybWF0aW9uIGZyb20gdGhlIHdlYnNpdGVzKSwgdGhlIFBVUlBPU0Ugb2YgdGhpcyBpbnZlc3RpZ2F0aW9uICh3aGljaCBpcyB0byBoZWxwIHRoZSBSU1BDQSBrbm93IHdoaWNoIGFyZWFzL2FuaW1hbHMgdG8gZm9jdXMgdGhlaXIgZWZmb3J0cyBvbiksIGFzIEknbSBpbnRyb2R1Y2luZyB0aGUgZGF0YXNldHMgSSBjYW4gaW50cm9kdWNlIHRoZSB0d28gZGlmZmVyZW50IGNpdGllcy4gRmlyc3QsIHdlIGNhbiB0YWxrIGEgc2hvcnQgYml0IGFib3V0IEF1c3RyYWxpYSBhcyBhIHdob2xlLCBpdCdzIGNsaW1hdGUsIHRoZSBraW5kIG9mIGFuaW1hbHMgZXRjLiBUaGUgcG9pbnQgaGVyZSBpcyB0byByZWFsbHkgc2V0IHRoZSBzY2VuZSBiZWZvcmUgZGl2aW5nIHRvbyBkZWVwIGludG8gZmFjdHMgYW5kIGZpZ3VyZXMsIGFzIGVzcGVjaWFsbHkgYSBub24tdGVjaG5pY2FsIGF1ZGllbmNlIHRoaXMgd2lsbCBoZWxwIGtlZXAgdGhlbSBlbmdhZ2VkIGFuZCBtYWtlIGEgbW9yZSBob2xpc3RpYyBwcmVzZW50YXRpb24uIEluIG15IG9waW5pb24sIGl0J3MgYWx3YXlzIGdvb2QgdG8gem9vbSBvdXQgYW5kIHNlZSB0aGUgYmlnIHBpY3R1cmUsIHJhdGhlciB0aGFuIGdldHRpbmcgbG9zdCBpbiB0aGUgbXlvcGlhIG9mIHNvbWUgY3N2IGZpbGVzLgoKVG93bnN2aWxsZSBJbnRybzoKVG93bnN2aWxsZSBpcyBhIGNpdHkgb24gdGhlIG5vcnRoLWVhc3Rlcm4gY29hc3Qgb2YgUXVlZW5zbGFuZCwgQXVzdHJhbGlhLiBXaXRoIGEgcG9wdWxhdGlvbiBvZiAxODAsODIwIGFzIG9mIEp1bmUgMjAxOCwgaXQgaXMgdGhlIGxhcmdlc3Qgc2V0dGxlbWVudCBpbiBOb3J0aCBRdWVlbnNsYW5kOyBpdCBpcyB1bm9mZmljaWFsbHkgY29uc2lkZXJlZCBpdHMgY2FwaXRhbC4gW25vdGU6IHB1dCBhIG1hcCBvZiBBdXN0cmFsaWEgd2l0aCBRdWVlbnNsYW5kIGFuZCBUb3duc3ZpbGxlIGhpZ2hsaWdodGVkIGhlcmUuIFRhbGsgYSBsaXR0bGUgYml0IGFib3V0IHRoZSBwb3B1bGF0aW9uIGRlbnNpdHksIHVyYmFuaXNhdGlvbiwgY2xpbWF0ZSwgdHlwZXMgb2YgYW5pbWFscyB0aGF0IGFyZSBjb21tb24gaGVyZSBldGMuIFNob3cgc29tZSBwaG90b3Mgb2YgdGhlIGFyZWEgdG9vXQoKQnJpc2JhbmUgSW50cm86CkV4YWN0IHNhbWUgYXMgYWJvdmUKCiMjIyAzLgphKSBUb3RhbCBjYWxsIHZvbHVtZSBmb3IgY29tcGxhaW50IGNhbGxzOiBIb3cgaGFzIHRoaXMgdHJlbmRlZCBvdmVyIHRpbWU/CgpGaXJzdCwgbGV0J3MgbG9vayBhdCB0aGUgVG93bnN2aWxsZSBhbmltYWwgY29tcGxhaW50cy4KYGBge3J9CmFuaW1hbF9jb21wbGFpbnRzICU+JSAKICBncm91cF9ieShkYXRlX3JlY2VpdmVkKSAlPiUgCiAgc3VtbWFyaXNlKGNvdW50ID0gbigpKSAlPiUgCiAgZ2dwbG90KGFlcyh4ID0gZGF0ZV9yZWNlaXZlZCwgeSA9IGNvdW50KSkgKwogIGdlb21fbGluZSgpICsKICBzY2FsZV94X2RhdGUoZGF0ZV9icmVha3MgPSAiNiBtb250aHMiLCBkYXRlX2xhYmVscyA9ICIlYi0leSIpCmBgYApUaGlzIHNob3dzIHNvbWUgc2Vhc29uYWxpdHkgYW5kIGFsc28gYW4gaW5jcmVhc2UgdGhlbiBhIGRlY2xpbmUuIEVhY2ggc3VtbWVyIChpbiBEZWNlbWJlcikgdGhlIGNhbGxzIGFyZSBtdWNoIGxvd2VyLCByaXNpbmcgYWdhaW4gZWFjaCBXaW50ZXIuIFVzaW5nIGdlb21fc21vb3RoLCB3ZSBnZXQ6CgpgYGB7cn0KYW5pbWFsX2NvbXBsYWludHMgJT4lIAogIGdyb3VwX2J5KGRhdGVfcmVjZWl2ZWQpICU+JSAKICBzdW1tYXJpc2UoY291bnQgPSBuKCkpICU+JSAKICBnZ3Bsb3QoYWVzKHggPSBkYXRlX3JlY2VpdmVkLCB5ID0gY291bnQpKSArCiAgZ2VvbV9zbW9vdGgoKSArCiAgZ2VvbV9wb2ludCgpICsKICBzY2FsZV94X2RhdGUoZGF0ZV9icmVha3MgPSAiMSB5ZWFyIiwgZGF0ZV9sYWJlbHMgPSAiJXkiKQpgYGAKClRoaXMgc2hvd3MgYSBiaXQgbW9yZSBjbGVhcmx5IHRoZSBnZW5lcmFsIHRyZW5kIG9mIGNhbGwgdm9sdW1lLiBGcm9tIDIwMTQgaXQgc3RlYWRpbHkgcmlzZXMsIHBlYWtpbmcgaW4gMjAxNy4gQWZ0ZXJ3YXJkcywgaXQgc3RlYWRpbHkgZGVjbGluZXMgdG8gb25seSBzbGlnaHRseSBoaWdoZXIgdGhhbiB3aGVyZSBpdCBzdGFydGVkLiBJdCB3b3VsZCBiZSB2ZXJ5IGRpZmZpY3VsdCB0byBzYXkgd2hldGhlciB0aGlzIHRyZW5kIHdpbGwgY29udGludWUgZG93bndhcmQsIGdvIHVwd2FyZCBvciBzdGF5IHJlbGF0aXZlbHkgZmxhdC4KCgoKCgoKCk5vdGU7IGlmIHdlIGhhdmUgdGltZSBvciBpZiBpdCdzIGhlbHBmdWwsIHdlIHdpbGwgZml4IHRoaXMgZ3JhcGggc28gdGhhdCBxdWFydGVycyBhcmUgcHJvcGVybHkgZGlzcGxheWVkLgpgYGB7cn0KYnJpc2JhbmVfY29tcGxhaW50cyAlPiUgCiAgZ3JvdXBfYnkoZGF0ZSkgJT4lIAogIHN1bW1hcmlzZShjb3VudCA9IG4oKSkgJT4lIAogIGdncGxvdChhZXMoeCA9IGRhdGUsIHkgPSBjb3VudCkpICsKICBnZW9tX3BvaW50KCkgKwogIGdlb21fbGluZSgpICsKICBzY2FsZV94X2RhdGUoZGF0ZV9icmVha3MgPSAiMyBtb250aHMiLCBkYXRlX2xhYmVscyA9ICIleSIpCmBgYAoKQWdhaW4sIHdlIHNlZSB0aGUgc2Vhc29uYWxpdHkgb2Ygd2ludGVyIGhhdmluZyBtb3JlIGNhbGxzLiBUaGUgZmFjdCB0aGlzIGlzIGluIGJvdGggQnJpc2JhbmUgYW5kIFRvd25zdmlsbGUgc3VnZ2VzdHMgYSBmYWlybHkgZ2VuZXJhbCB0cmVuZC4KCmBgYHtyfQpicmlzYmFuZV9jb21wbGFpbnRzICU+JSAKICBncm91cF9ieShkYXRlKSAlPiUgCiAgc3VtbWFyaXNlKGNvdW50ID0gbigpKSAlPiUgCiAgZ2dwbG90KGFlcyh4ID0gZGF0ZSwgeSA9IGNvdW50KSkgKwogIGdlb21fcG9pbnQoKSArCiAgZ2VvbV9zbW9vdGgoKSArCiAgc2NhbGVfeF9kYXRlKGRhdGVfYnJlYWtzID0gIjEgeWVhciIsIGRhdGVfbGFiZWxzID0gIjIwJXkiKQpgYGAKCk90aGVyIHRoYW4gZGVjbGluaW5nIGEgbGl0dGxlIG92ZXIgMjAxNiwgdGhlIG51bWJlciBvZiBjYWxscyBzZWVzIGEgc2xvdyBidXQgc3RlYWR5IGluY3JlYXNlIHRvd2FyZHMgMjAyMCwgYmVpbmcgdGhvdXNhbmRzIG1vcmUgdGhhbiBpdCB3YXMgaW4gMjAxNiBhbmQgMjAxNy4gU28sIHRoZSBnZW5lcmFsIHRyZW5kIGlzIHRoYXQgdGhlIFJTUENBIGFyZSBnZXR0aW5nIG1vcmUgY29tcGxhaW50cyBhcyB0aW1lIGdvZXMgb24uIE5vdywgdGhpcyBkb2VzIG5vdCBuZWNlc3NhcmlseSBtZWFuIHRoZSBsaW5lIHdpbGwgY29udGludWUgdG8gZ28gdXAuIFdlIGFyZSBhbHNvIG1pc3NpbmcgUTMgZnJvbSAyMDE2IHNvIHRoaXMgc2tld3MgdGhlIGN1cnZlIGEgbGl0dGxlCgoKCiMjIyAzLgpiKSBJcyB0aGVyZSBhIHBhcnRpY3VsYXIgYW5pbWFsIGJlaW5nIGNhbGxlZCBhYm91dCB0aGUgbW9zdD8KCmBgYHtyfQphbmltYWxfY29tcGxhaW50cyAlPiUgCiAgZ3JvdXBfYnkoYW5pbWFsX3R5cGUpICU+JSAKICBnZ3Bsb3QoYWVzKHggPSBhbmltYWxfdHlwZSkpICsKICBnZW9tX2JhcigpCmBgYAoKVGhlIG51bWJlciBvZiBjYWxscyBhYm91dCBkb2dzIGR3YXJmIHRob3NlIGFib3V0IGNhdHMgaHVnZWx5LiBMZXQncyBsb29rIGF0IHNwZWNpZmljIG51bWJlcnM6CmBgYHtyfQphbmltYWxfY29tcGxhaW50cyAlPiUgCiAgZ3JvdXBfYnkoYW5pbWFsX3R5cGUpICU+JQogIGNvdW50KCkgJT4lIAogIHN1bW1hcmlzZShuLCA0MDk0IC8gMzgzMTkpCmBgYAoKU28gY2F0cyBhY2NvdW50IGZvciBvbmx5IDEwJSBvZiB0aGUgY2FsbHMgZG9ncyBkbyBmb3IgVG93bnN2aWxsZSEgTGV0J3MgbG9vayBhdCBCcmlzYmFuZToKCmBgYHtyfQpicmlzYmFuZV9jb21wbGFpbnRzICU+JSAKICBncm91cF9ieSh0eXBlX29mX2FuaW1hbCkgJT4lCiAgY291bnQoKQoKYnJpc2JhbmVfY29tcGxhaW50cyAlPiUgCiAgZ3JvdXBfYnkodHlwZV9vZl9hbmltYWwpICU+JQogIGdncGxvdChhZXMoeCA9IHR5cGVfb2ZfYW5pbWFsKSkgKwogIGdlb21fYmFyKCkKYGBgCgpXZSBoYXZlIGEgbG90IG1vcmUgYW5pbWFsIHR5cGVzIGhlcmUgdGhhdCB3ZSBkb24ndCBpbiB0aGUgcHJldmlvdXMgZGF0YS4gV2UgYWxzbyBoYXZlIG1hbnkgY2FsbHMgYWJvdXQgQXR0YWNrcyB3aXRoIG5vIGFuaW1hbCBzcGVjaWZpZWQsIG1hbnkgb2Ygd2hpY2ggaXQgaXMgdmVyeSBsaWtlbHkgdGhleSB3ZXJlIGludm9sdmluZyBkb2dzLiBIb3dldmVyLCB3ZSBjYW4ndCBzYXkgdGhpcyBmb3Igc3VyZS4KClNvIHRoYXQgbWFrZXMgCmBgYHtyfQo0NzQ1IC8gMTMzMzQgICMgY2F0cyBhcmUgMzUlIG9mIHRoZSBjYWxscyBjb21wYXJlZCB0byBkb2dzCgoKCiMgYWxsIG90aGVyIGFuaW1hbHMgZGl2aWRlZCBieSBkb2dzLCBsZWF2aW5nIG91dCB1bnNwZWNpZmllZCAod2hpY2ggd2UgYmVsaWV2ZSBwb3RlbnRpYWxseSBjb250YWluIGEgaGlnaCBwcm9wb3J0aW9uIG9mIGRvZ3MpCjk0NTcgLyAxMzM0OQpgYGAKCk1vc3Qgb2YgdGhlIG90aGVyIGFuaW1hbHMgaGF2ZSB2ZXJ5IHNtYWxsIGNvdW50cywgaW50ZXJlc3RpbmdseSBmb3hlcyBzZWVtIHRvIG1ha2UgdXAgYSBkZWNlbnQgcHJvcG9ydGlvbiBvZiB0aGUgY2FsbHMgcmVnYXJkaW5nIHdpbGQgYW5pbWFscy4KClRvIGFuc3dlciB0aGUgcXVlc3Rpb24gaG93ZXZlciwgaXQncyBtYWlubHkgZG9ncyBhbmQgY2F0cywgYW5kIGVzcGVjaWFsbHkgZG9ncy4gRG9ncyBhcmUgYmVpbmcgY2FsbGVkIGFib3V0IG1vcmUgdGhhbiBhbnkgb2YgdGhlIG90aGVyIGFuaW1hbHMgY29tYmluZWQgKGlmIHdlIGxlYXZlIFVuc3BlY2lmaWVkIHRvIHRoZSBzaWRlKQoKKEF0dGFjayByZWZlcnMgdG8gdGhlIGluaXRpYWwgZGVzY3JpcHRpb24gb2YgdGhlIGNvbXBsYWludCkKCgojIyMgMy4gCmMpIERvIHBhcnRpY3VsYXIgc3VidXJicyBoYXZlIGRpZmZlcmVudCB0eXBlIG9mIGNvbXBsYWludCBjYWxscz8gRG8gdGhleSBjYWxsIGFib3V0IGRpZmZlcmVudCBhbmltYWxzPwoKT0ssIHNvIHRoaXMgb25lIGlzIGRpZmZpY3VsdCBzaW1wbHkgZm9yIHRoZSBmYWN0IHRoZXJlIGlzIGEgaHVnZSBhbW91bnQgb2Ygc3VidXJicy4KYGBge3J9CmJyaXNiYW5lX2NvbXBsYWludHMgJT4lIAogIGdyb3VwX2J5KHN1YnVyYikgJT4lIAogIGNvdW50KCkKCiMgVGhlcmUgaXMgMTkyIHN1YnVyYnMhIENlcnRhaW5seSB1c2luZyBhIGZpbGwgb24gYSBncmFwaCBpcyBub3QgZ29ubmEgd29yaywgbmVpdGhlciBpcyBwdXR0aW5nIHRoZW0gb24gdGhlIHgtYXhpcyBvbiBhIGJhciBncmFwaC4KCmFuaW1hbF9jb21wbGFpbnRzICU+JSAKICBncm91cF9ieShzdWJ1cmIpICU+JSAKICBjb3VudCgpCiMgODUgc3VidXJicyBmb3IgVG93bnN2aWxsZQoKYW5pbWFsX2NvbXBsYWludHMgJT4lIAogIGdyb3VwX2J5KGVsZWN0b3JhbF9kaXZpc2lvbikgJT4lIAogIGNvdW50KCkKIyBhbHNvIDExIGVsZWN0b3JhbCBkaXZpc2lvbnMuIENvdWxkIHdlIGxvb2sgYXQgc3VidXJicyBvbmUgZWxlY3RvcmFsIGRpdmlzaW9uIGF0IGEgdGltZT8gUG9zc2libHkKYGBgCgpJZGVhOiBXaGF0IGFib3V0IHVzaW5nIGxlYWZsZXQgdG8gdmlzdWFsaXNlIHR5cGVzIG9mIGNvbXBsYWludCBjYWxscyBvbiBhIG1hcD8KClRoaXMgaXMgbW9yZSBmZWFzaWJsZSB3aXRoIHRoZSBUb3duc3ZpbGxlIGRhdGFzZXRzLCBhcyBpdCBoYXMgbGVzcyBzdWJ1cmJzIGFuZCBvbmx5IDYgdHlwZXMgb2YgY29tcGxhaW50cy4gSXQgbWF5IGJlIG5lY2Vzc2FyeSB0byB0cnkgYW5kIHdyYW5nbGUgdGhlIEJyaXNiYW5lIGRhdGEgYSBsaXR0bGUgZnVydGhlciB0byBuYXJyb3cgZG93biBjYXRlZ29yaWVzIChmb3IgYm90aCB0eXBlX29mX2FuaW1hbCBhbmQgY29tcGxhaW50X3R5cGUpCgpGT1IgVE9XTlNWSUxMRSBXRSBIQVZFOgo4NSBkaWZmZXJlbnQgc3VidXJicwo2IGNvbXBsYWludCB0eXBlcwoyIGFuaW1hbCB0eXBlcwoKV2Ugd2FudCB0byBicmVhayBpdCBkb3duIGJ5IHN1YnVyYiBhbmQgY29tcGxhaW50IHR5cGUsIGFuZCB0aGVuIGJ5IHN1YnVyYiBhbmQgYW5pbWFsIHR5cGUKYGBge3J9CmFuaW1hbF9jb21wbGFpbnRzICU+JSAKICBnZ3Bsb3QoYWVzKHggPSBzdWJ1cmIsIGZpbGwgPSBhbmltYWxfdHlwZSkpICsKICBnZW9tX2Jhcihwb3NpdGlvbiA9ICJmaWxsIikgKwogIGNvb3JkX2ZsaXAoKSArCiAgc2NhbGVfeF9kaXNjcmV0ZShndWlkZSA9IGd1aWRlX2F4aXMobi5kb2RnZSA9IDUpKQpgYGAKCmBgYHtyfQphbmltYWxfY29tcGxhaW50cyAlPiUgCiAgZ2dwbG90KGFlcyh4ID0gc3VidXJiLCBmaWxsID1jb21wbGFpbnRfdHlwZSkpICsKICBnZW9tX2Jhcihwb3NpdGlvbiA9ICJmaWxsIikgCiAgI2Nvb3JkX2ZsaXAoKSArCiAgI3NjYWxlX3hfZGlzY3JldGUoZ3VpZGUgPSBndWlkZV9heGlzKG4uZG9kZ2UgPSA1KSkKYGBgCgpUaGUgY2hhbGxlbmdlIGFnYWluLCBpcyBoYXZpbmcgdG9vIG1hbnkgc3VidXJicyB0aGF0IHdlIGNhbid0IGdldCBhbnkgdXNlZnVsIGluZm9ybWF0aW9uIG91dCBvZiB0aGUgZ3JhcGhzCgpgYGB7cn0KYW5pbWFsX2NvbXBsYWludHMgJT4lIAogIGdyb3VwX2J5KHN1YnVyYikgJT4lIAogIGNvdW50KHNvcnQgPSBUUlVFKQoKIyBsZXQncyBkcm9wIGFueSBzdWJ1cmJzIHdpdGggbGVzcyB0aGFuIDIwMCBjYXNlcwoKYW5pbWFsX2NvbXBsYWludHMgJT4lIAogIGdyb3VwX2J5KHN1YnVyYikgJT4lIAogIHN1bW1hcmlzZShjb3VudCA9IG4oKSwgYW5pbWFsX3R5cGUpICU+JSAKICBmaWx0ZXIoY291bnQgPj0gNTAwKSAlPiUgCiAgZ2dwbG90KGFlcyh4ID0gc3VidXJiLCB5ID0gY291bnQsIGZpbGwgPSBhbmltYWxfdHlwZSkpICsKICBnZW9tX2NvbCgpICsKICBjb29yZF9mbGlwKCkKYGBgCgpUaGUgaGlnaGVzdCBjb3VudCBieSBxdWl0ZSBhIGxhcmdlIG1hcmdpbiBpcyB1bmFsbG9jYXRlZCB0byBhIHNwZWNpZmljIHN1YnVyYi4KCmBgYHtyfQphbmltYWxfY29tcGxhaW50cyAlPiUgCiAgZ3JvdXBfYnkoc3VidXJiKSAlPiUgCiAgc3VtbWFyaXNlKGNvdW50ID0gbigpLCBhbmltYWxfdHlwZSkgJT4lIAogIGZpbHRlcihjb3VudCA+PSA1MDApICU+JSAKICBnZ3Bsb3QoYWVzKHggPSBzdWJ1cmIsIHkgPSBjb3VudCwgZmlsbCA9IGFuaW1hbF90eXBlKSkgKwogIGdlb21fY29sKHBvc2l0aW9uID0gImZpbGwiKSArCiAgY29vcmRfZmxpcCgpIApgYGAKQXQgYSBnbGFuY2UsIHRoZXJlJ3Mgbm8gYmlnIGRpZmZlcmVuY2Ugb24gYW5pbWFsIHR5cGVzLiBBbGwgdGhlIHN1YnVyYnMgaGF2ZSBhIGxhcmdlIG1ham9yaXR5IG9mIGRvZ3MuIENvdWxkIHdlIGRvIGEgaHlwb3RoZXNpcyB0ZXN0IHRvIHNlZSBpZiB0aGVyZSBpcyBhIHN0YXRpc3RpY2FsbHkgc2lnbmlmaWNhbnQgZGlmZmVyZW5jZT8KCmBgYHtyfQphbmltYWxfY29tcGxhaW50cyAlPiUgCiAgZ3JvdXBfYnkoc3VidXJiKSAlPiUgCiAgc3VtbWFyaXNlKGNvdW50ID0gbigpLCBhbmltYWxfdHlwZSkgJT4lIAogIGZpbHRlcihjb3VudCA8IDUwMCAmIGNvdW50ID4gMTAwKSAlPiUgCiAgZ2dwbG90KGFlcyh4ID0gc3VidXJiLCB5ID0gY291bnQsIGZpbGwgPSBhbmltYWxfdHlwZSkpICsKICBnZW9tX2NvbChwb3NpdGlvbiA9ICJmaWxsIikgKwogIGNvb3JkX2ZsaXAoKSAKYGBgCkxvb2tpbmcgYXQgdGhlIGxvd2VyIGVuZCBvZiB0aGUgcG9wdWxhdGlvbiwgd2Ugc2VlIGFuIG91dGxpZXIuIFRvd25zdmlsbGUgQ2l0eSBoYXMgd2F5IG1vcmUgY2F0cyB0aGFuIGFueSBvZiB0aGUgb3RoZXIgc3VidXJicy4gSW4gZmFjdCwgaXQncyBhbG1vc3QgNTAvNTAhCgpOb3cgc3RpbGwgbG9va2luZyBhdCB0aGUgVG93bnN2aWxsZSBkYXRhc2V0LCB3ZSdsbCBicmVhayBpdCBkb3duIGJ5IGNvbXBsYWludCB0eXBlOgpgYGB7cn0KYW5pbWFsX2NvbXBsYWludHMgJT4lIAogIGdyb3VwX2J5KHN1YnVyYikgJT4lIAogIHN1bW1hcmlzZShjb3VudCA9IG4oKSwgY29tcGxhaW50X3R5cGUpICU+JSAKICBmaWx0ZXIoY291bnQgPj0gNTAwICYgY291bnQgPD0gNDAwMCkgJT4lIAogIGdncGxvdChhZXMoeCA9IHN1YnVyYiwgeSA9IGNvdW50LCBmaWxsID0gY29tcGxhaW50X3R5cGUpKSArCiAgZ2VvbV9jb2wocG9zaXRpb24gPSAiZmlsbCIpICsKICBjb29yZF9mbGlwKCkgCmBgYAoKTm93IGZvciB0aGUgbG93ZXIgZW5kIG9mIHRoZSBjb3VudDoKYGBge3J9CmFuaW1hbF9jb21wbGFpbnRzICU+JSAKICBncm91cF9ieShzdWJ1cmIpICU+JSAKICBzdW1tYXJpc2UoY291bnQgPSBuKCksIGNvbXBsYWludF90eXBlKSAlPiUgCiAgZmlsdGVyKGNvdW50IDwgNTAwICYgY291bnQgPiA1MCkgJT4lIAogIGdncGxvdChhZXMoeCA9IHN1YnVyYiwgeSA9IGNvdW50LCBmaWxsID0gY29tcGxhaW50X3R5cGUpKSArCiAgZ2VvbV9jb2wocG9zaXRpb24gPSAiZmlsbCIpICsKICBjb29yZF9mbGlwKCkgCmBgYAoKSSdtIG5vdCBzdXJlIG11Y2ggY2FuIGJlIGdsZWFtZWQgd2l0aCBzbyBtYW55IGNvbXBsYWludF90eXBlcy4gTGV0J3MgdHJ5IGZvY3VzaW5nIG1vcmUgc3BlY2lmaWNhbGx5LgoKT25lIHRoaW5nIHRvIG5vdGUgaGVyZSwgaXMgdGhlIHZhc3QgdmFyaWF0aW9uIGluIHRvbGVyYW5jZSBmb3Igbm9pc2UuIE1vc3QgY2F0ZWdvcmllcyBhcmUgY29uc2lzdGVudCBleGNlcHQgdGhpcyBvbmUuIENsdWRlbiBmb3IgZXhhbXBsZSBoYXMgYSBzbWFsbCBwZXJjZW50YWdlIG9mIG5vaXNlIGNvbXBsYWludHMsd2hpbGUgQm9obGUgUGxhaW5zIGhhcyBhIGh1Z2UgcGVyY2VudGFnZS4gVGhpcyByZXF1aXJlcyBtb3JlIGludmVzdGlnYXRpb24gdG8gZmlndXJlIG91dCB0aGUgcm9vdCBjYXVzZSBvZiB0aGlzOiAKCmBgYHtyfQphbmltYWxfY29tcGxhaW50cyAlPiUgCiAgZ3JvdXBfYnkoc3VidXJiKSAlPiUgCiAgc3VtbWFyaXNlKGNvdW50ID0gbigpLCBjb21wbGFpbnRfdHlwZSkgJT4lIAogIGZpbHRlcihjb3VudCA+PSA1MDApICU+JSAKICBmaWx0ZXIoY29tcGxhaW50X3R5cGUgPT0gIk5vaXNlIiB8IChjb21wbGFpbnRfdHlwZSA9PSAiQXR0YWNrIikpICU+JSAKICBnZ3Bsb3QoYWVzKHggPSBzdWJ1cmIsIHkgPSBjb3VudCwgZmlsbCA9IGNvbXBsYWludF90eXBlKSkgKwogIGdlb21fY29sKHBvc2l0aW9uID0gImZpbGwiKSArCiAgY29vcmRfZmxpcCgpIAoKYW5pbWFsX2NvbXBsYWludHMgJT4lIAogIGdyb3VwX2J5KHN1YnVyYikgJT4lIAogIHN1bW1hcmlzZShjb3VudCA9IG4oKSwgY29tcGxhaW50X3R5cGUpICU+JSAKICBmaWx0ZXIoY291bnQgPj0gNTAwKSAlPiUgCiAgZmlsdGVyKGNvbXBsYWludF90eXBlID09ICJOb2lzZSIgfCAoY29tcGxhaW50X3R5cGUgPT0gIkFnZ3Jlc3NpdmUgQW5pbWFsIikpICU+JSAKICBnZ3Bsb3QoYWVzKHggPSBzdWJ1cmIsIHkgPSBjb3VudCwgZmlsbCA9IGNvbXBsYWludF90eXBlKSkgKwogIGdlb21fY29sKHBvc2l0aW9uID0gImZpbGwiKSArCiAgY29vcmRfZmxpcCgpIAoKYW5pbWFsX2NvbXBsYWludHMgJT4lIAogIGdyb3VwX2J5KHN1YnVyYikgJT4lIAogIHN1bW1hcmlzZShjb3VudCA9IG4oKSwgY29tcGxhaW50X3R5cGUpICU+JSAKICBmaWx0ZXIoY291bnQgPj0gNTAwKSAlPiUgCiAgZmlsdGVyKGNvbXBsYWludF90eXBlID09ICJXYW5kZXJpbmciIHwgKGNvbXBsYWludF90eXBlID09ICJBZ2dyZXNzaXZlIEFuaW1hbCIpKSAlPiUgCiAgZ2dwbG90KGFlcyh4ID0gc3VidXJiLCB5ID0gY291bnQsIGZpbGwgPSBjb21wbGFpbnRfdHlwZSkpICsKICBnZW9tX2NvbChwb3NpdGlvbiA9ICJmaWxsIikgKwogIGNvb3JkX2ZsaXAoKSAKCmFuaW1hbF9jb21wbGFpbnRzICU+JSAKICBncm91cF9ieShzdWJ1cmIpICU+JSAKICBzdW1tYXJpc2UoY291bnQgPSBuKCksIGNvbXBsYWludF90eXBlKSAlPiUgCiAgZmlsdGVyKGNvdW50ID49IDUwMCkgJT4lIAogIGZpbHRlcihjb21wbGFpbnRfdHlwZSA9PSAiRW5jbG9zdXJlIiB8IChjb21wbGFpbnRfdHlwZSA9PSAiTm9pc2UiKSkgJT4lIAogIGdncGxvdChhZXMoeCA9IHN1YnVyYiwgeSA9IGNvdW50LCBmaWxsID0gY29tcGxhaW50X3R5cGUpKSArCiAgZ2VvbV9jb2wocG9zaXRpb24gPSAiZmlsbCIpICsKICBjb29yZF9mbGlwKCkgCmBgYAoKRm9yIHRoZSBsZXNzIHRoYW4gNTAwIGdyZWF0ZXIgdGhhbiA1MCBncm91cHM6CmBgYHtyfQphbmltYWxfY29tcGxhaW50cyAlPiUgCiAgZ3JvdXBfYnkoc3VidXJiKSAlPiUgCiAgc3VtbWFyaXNlKGNvdW50ID0gbigpLCBjb21wbGFpbnRfdHlwZSkgJT4lIAogIGZpbHRlcihjb3VudCA8IDUwMCAmIGNvdW50ID4gMTAwKSAlPiUgCiAgZmlsdGVyKGNvbXBsYWludF90eXBlID09ICJOb2lzZSIgfCAoY29tcGxhaW50X3R5cGUgPT0gIkF0dGFjayIpKSAlPiUgCiAgZ2dwbG90KGFlcyh4ID0gc3VidXJiLCB5ID0gY291bnQsIGZpbGwgPSBjb21wbGFpbnRfdHlwZSkpICsKICBnZW9tX2NvbChwb3NpdGlvbiA9ICJmaWxsIikgKwogIGNvb3JkX2ZsaXAoKSAKCmFuaW1hbF9jb21wbGFpbnRzICU+JSAKICBncm91cF9ieShzdWJ1cmIpICU+JSAKICBzdW1tYXJpc2UoY291bnQgPSBuKCksIGNvbXBsYWludF90eXBlKSAlPiUgCiAgZmlsdGVyKGNvdW50IDwgNTAwICYgY291bnQgPiAxMDApICU+JSAgCiAgZmlsdGVyKGNvbXBsYWludF90eXBlID09ICJOb2lzZSIgfCAoY29tcGxhaW50X3R5cGUgPT0gIkFnZ3Jlc3NpdmUgQW5pbWFsIikpICU+JSAKICBnZ3Bsb3QoYWVzKHggPSBzdWJ1cmIsIHkgPSBjb3VudCwgZmlsbCA9IGNvbXBsYWludF90eXBlKSkgKwogIGdlb21fY29sKHBvc2l0aW9uID0gImZpbGwiKSArCiAgY29vcmRfZmxpcCgpIAoKYW5pbWFsX2NvbXBsYWludHMgJT4lIAogIGdyb3VwX2J5KHN1YnVyYikgJT4lIAogIHN1bW1hcmlzZShjb3VudCA9IG4oKSwgY29tcGxhaW50X3R5cGUpICU+JSAKICBmaWx0ZXIoY291bnQgPCA1MDAgJiBjb3VudCA+IDEwMCkgJT4lIAogIGZpbHRlcihjb21wbGFpbnRfdHlwZSA9PSAiV2FuZGVyaW5nIiB8IChjb21wbGFpbnRfdHlwZSA9PSAiQWdncmVzc2l2ZSBBbmltYWwiKSkgJT4lIAogIGdncGxvdChhZXMoeCA9IHN1YnVyYiwgeSA9IGNvdW50LCBmaWxsID0gY29tcGxhaW50X3R5cGUpKSArCiAgZ2VvbV9jb2wocG9zaXRpb24gPSAiZmlsbCIpICsKICBjb29yZF9mbGlwKCkgCgphbmltYWxfY29tcGxhaW50cyAlPiUgCiAgZ3JvdXBfYnkoc3VidXJiKSAlPiUgCiAgc3VtbWFyaXNlKGNvdW50ID0gbigpLCBjb21wbGFpbnRfdHlwZSkgJT4lIAogIGZpbHRlcihjb3VudCA8IDUwMCAmIGNvdW50ID4gMTAwKSAlPiUgCiAgI2ZpbHRlcihjb21wbGFpbnRfdHlwZSA9PSAiRW5jbG9zdXJlIiB8IChjb21wbGFpbnRfdHlwZSA9PSAiTm9pc2UiKSkgJT4lIAogIGdncGxvdChhZXMoeCA9IHN1YnVyYiwgeSA9IGNvdW50LCBmaWxsID0gY29tcGxhaW50X3R5cGUpKSArCiAgZ2VvbV9jb2wocG9zaXRpb24gPSAiZmlsbCIpICsKICBjb29yZF9mbGlwKCkgKwogIGZhY2V0X3dyYXAofiBzdWJ1cmIpCmBgYAoKCmBgYHtyfQphbmltYWxfY29tcGxhaW50cyAlPiUgCiAgZ3JvdXBfYnkoc3VidXJiKSAlPiUgCiAgc3VtbWFyaXNlKGNvdW50ID0gbigpLCBjb21wbGFpbnRfdHlwZSwgYW5pbWFsX3R5cGUpICU+JSAKICBmaWx0ZXIoY291bnQgPCA1MDAgJiBjb3VudCA+IDEwMCkgJT4lIAogIGdncGxvdChhZXMoeCA9IGNvbXBsYWludF90eXBlLCB5ID0gY291bnQsIGZpbGwgPSBjb21wbGFpbnRfdHlwZSkpICsKICBnZW9tX2NvbCgpICsKICBmYWNldF93cmFwKH4gc3VidXJiKQpgYGAKCkZyb20gdGhpcyBncmFwaCwgd2UgY2FuIHNlZSB0aGF0IEh5ZGUgUGFyayBoYXMgYSBkaXNwcm9wb3J0aW9uYXRlIGFtb3VudCBvZiBwcml2YXRlIGltcG91bmRzLCB3aGlsZSBCb2hsZSBwbGFpbnMgaGFzIG1vcmUgbm9pc2UgY29tcGxhaW50cy4KClBvdGVudGlhbCBoeXBvdGhlc2lzIHRlc3Q6CgpUaGF0IHRoZSBsZXZlbCBvZiBwcml2YXRlIGltcG91bmRzIGluIEh5ZGUgUGFyayBiZWluZyBncmVhdGVyIGlzIHN0YXRpc3RpY2FsbHkgc2lnbmlmaWNhbnQuCgpUaGF0IHRoZSBsZXZlbCBvZiBub2lzZSBpbiBCb2hsZSBQbGFpbnMgYmVpbmcgZ3JlYXRlciBpcyBzdGF0aXN0aWNhbGx5IHNpZ25pZmljYW50LgpgYGB7cn0KYW5pbWFsX2NvbXBsYWludHMgJT4lIAogIGdyb3VwX2J5KHN1YnVyYikgJT4lIAogIGNvdW50KCkgJT4lIAogIGZpbHRlcihuIDwgNTAwICYgbiA+IDEwMCkKYGBgCgoKCgoKCkxldCdzIGxvb2sgYXQgdGhlIHN1YnVyYnMgd2l0aCBtdWNoIGhpZ2hlciBjb21wbGFpbnRzIG5vdzoKCmBgYHtyfQphbmltYWxfY29tcGxhaW50cyAlPiUgCiAgZ3JvdXBfYnkoc3VidXJiKSAlPiUgCiAgc3VtbWFyaXNlKGNvdW50ID0gbigpLCBjb21wbGFpbnRfdHlwZSwgYW5pbWFsX3R5cGUpICU+JSAKICBmaWx0ZXIoY291bnQgPj0gNTAwICYgY291bnQgPDQwMDApICU+JSAKICBnZ3Bsb3QoYWVzKHggPSBjb21wbGFpbnRfdHlwZSwgeSA9IGNvdW50LCBmaWxsID0gY29tcGxhaW50X3R5cGUpKSArCiAgZ2VvbV9jb2woKSArCiAgZmFjZXRfd3JhcCh+IHN1YnVyYikKYGBgCgoKCgoKIyMjIDIuIGEpIElzIHRoZXJlIGFyZSBhIHRyZW5kIGluIGluanVyaWVzIEJ5IFJlZ2lvbiwgYW5kIGlzIHRoZXJlIGRpZmZlcmVudCBwZWFrcyBvZiB0aW1lcyBvZiB5ZWFyIHBlciByZWdpb24/CgpJdCdzIGltcG9zc2libGUgdG8gc2F5IGlmIHRoZXJlJ3MgZGlmZmVyZW50IHBlYWtzIG9mIHRpbWVzIG9mIHllciBwZXIgcmVnaW9uLCBhcyB3ZSBvbmx5IGhhdmUgdGhlIGRhdGEgZm9yIHRoZSB5ZWFyIGFzIGEgd2hvbGUuIFVubGVzcyB3ZSBsb29rIGF0IFN1YnVyYiByYXRoZXIgdGhhbiByZWdpb24sIGFuZCBicmVhayB0aGlzIGRvd24gYnkgdGltZS4gSG93ZXZlciwgSSB0aGluayBpdCdkIGJlIGdvb2QgdG8gdXNlIHRoZSBnZW5lcmFsIEF1dHJhbGlhIChuYXRpb253aWRlKSBkYXRhLgoKCgoKCgoKCgpgYGB7cn0KYW5pbWFsX291dGNvbWVzICU+JSAKICBncm91cF9ieShyZWdpb24pICU+JSAKICBnZ3Bsb3QoYWVzKHggPSByZWdpb24sIHkgPSBudW1iZXJfb2Zfb2NjdXJlbmNlcywgZmlsbCA9IG91dGNvbWUsIGNvbCA9IG91dGNvbWUpKSArCiAgZ2VvbV9jb2wocG9zaXRpb24gPSAiZmlsbCIpCmBgYAoKCmBgYHtyfQphbmltYWxfb3V0Y29tZXMgJT4lIAogIGdyb3VwX2J5KHJlZ2lvbiwgeWVhcikgJT4lIAogIHN1bW1hcmlzZShjb3VudCA9IG4oKSkgJT4lIAogIGdncGxvdChhZXMoeCA9IHllYXIsIHkgPSBjb3VudCkpICsKICAjZ2VvbV9wb2ludCgpICsKICBnZW9tX2xpbmUoKSArCiAgZmFjZXRfd3JhcCh+IHJlZ2lvbikKYGBgCgoKCgoKCgoKCgoKCgoKCgoKCgo=